package com.semidata.trp.monitor.job;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponseStatus;

import com.semidata.rtd.core.executor.TaskExecutor;
import com.semidata.rtd.core.executor.TaskExecutorService;
import com.semidata.rtd.core.executor.ThreadPoolTaskExecutor;
import com.semidata.rtd.core.http.server.HttpResponse;
import com.semidata.rtd.core.http.server.HttpSession;
import com.semidata.rtd.core.job.AbstractJob;
import com.semidata.rtd.core.job.JobCompleteHandler;
import com.semidata.rtd.core.job.SequenceTaskScheduler;
import com.semidata.rtd.core.job.TaskScheduler;
import com.semidata.rtd.core.log.Logger;
import com.semidata.rtd.core.service.ServiceManager;
import com.semidata.trp.monitor.frequency.TaskFrequency;
import com.semidata.trp.monitor.report.TaskReport;

public class MonitorJob extends AbstractJob<MonitorJobContext> {

    private TaskExecutor threadPoolTaskExecutor;
    private MonitorJobContext context;
    private SequenceTaskScheduler scheduler;

    private static byte GIF[] = { 71, 73, 70, 56, 57, 97, 1, 0, 1, 0, -128, -1, 0, -1, -1, -1, 0, 0, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 68, 1, 0, 59 };

    public MonitorJob(HttpSession session) {
        super(null);

        TaskExecutorService executorService = ServiceManager.getService(TaskExecutorService.class);
        this.threadPoolTaskExecutor = executorService.getTaskExecutor(ThreadPoolTaskExecutor.class);

        this.context = new MonitorJobContext(session);

        this.scheduler = new SequenceTaskScheduler();

        this.scheduler.addTask(new TaskLog(this, threadPoolTaskExecutor));
        this.scheduler.addTask(new TaskFrequency(this, threadPoolTaskExecutor));
        this.scheduler.addTask(new TaskReport(this, threadPoolTaskExecutor));
        
        this.scheduler.setJobCompleteHandler(new JobCompleteHandler() {

            public void handle(Throwable cause) {
                HttpSession session = context.getSession();

                try {
                    if (cause != null) {
                        Logger.log("ERROR", cause);
                        session.getResponse().error(HttpResponseStatus.BAD_REQUEST);
                    } else {
                        ByteBuf buffer = Unpooled.buffer();
                        buffer.writeBytes(GIF);
                        HttpResponse response = context.getSession().getResponse();
                        response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "image/GIF; charset=UTF-8");

                        MonitorRequest request = context.getMonitorRequest();
                        if (request.getType() == MonitorRequest.Type.CLK) {
                            response.setStatus(HttpResponseStatus.FOUND);
                            response.setHeader(HttpHeaders.Names.LOCATION, request.getLandingPage());
                        } else {
                            response.setStatus(HttpResponseStatus.OK);
                        }
                        session.getResponse().end(buffer);
                    }
                } catch (Exception e) {
                    Logger.log("ERROR", cause);
                    session.getResponse().error(HttpResponseStatus.BAD_REQUEST);
                }
            }
        });
    }

    public MonitorJobContext getJobContext() {
        return context;
    }

    public TaskScheduler getTaskScheduler() {
        return scheduler;
    }
}
